//
//  YsNumberView.m
//  YSKitExample
//
//  Created by Kyson on 2017/6/16.
//  Copyright © 2017年 YangShen. All rights reserved.
//

#import "YSNumberView.h"

#define kDefaultSize CGSizeMake(100, 30)
#define kDefaultMinNumber 1

@interface NSString (YSNumberButton)
/**
 字符串 nil, @"", @"  ", @"\n" Returns NO;
 其他 Returns YES.
 */
- (BOOL)isNotBlank;
@end

@implementation NSString (YSNumberButton)
- (BOOL)isNotBlank {
    NSCharacterSet *blank = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    for (NSInteger i = 0; i < self.length; ++i) {
        unichar c = [self characterAtIndex:i];
        if (![blank characterIsMember:c]) {
            return YES;
        }
    }
    return NO;
}

@end

@interface YSNumberView () <UITextFieldDelegate>
/// 减按钮
@property (nonatomic, strong) UIButton *decreaseBtn;
/// 加按钮
@property (nonatomic, strong) UIButton *increaseBtn;
/// 数量展示/输入框
@property (nonatomic, strong) UITextField *numberTextField;
/// 快速加减定时器
@property (nonatomic, strong) NSTimer *timer;
@end

@implementation YSNumberView

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setupUI];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (frame.size.width == 0 || frame.size.height == 0) {
        frame.size = kDefaultSize;
    }
    self = [super initWithFrame:frame];
    [self setupUI];
    return self;
}

+ (instancetype)numberViewWithFrame:(CGRect)frame {
    return [[self alloc] initWithFrame:frame];
}

- (void)setupUI {
    self.backgroundColor = [UIColor whiteColor];
    self.layer.cornerRadius = 3.f;
    self.clipsToBounds = YES;
    
    _shakeAnimation = NO;
    _decreaseHide = NO;
    _minValue = kDefaultMinNumber;
    _maxValue = NSIntegerMax;
    _numberFontSize = 15.f;
    _buttonFontSize = 17.f;
    _canInputNumber = YES;
    
    _increaseBtn = [self createButton];
    [_increaseBtn setTitle:@"+" forState:UIControlStateNormal];
    _decreaseBtn = [self createButton];
    [_decreaseBtn setTitle:@"-" forState:UIControlStateNormal];
    [self addSubview:_increaseBtn];
    [self addSubview:_decreaseBtn];
    
    _numberTextField = [[UITextField alloc] init];
    _numberTextField.delegate = self;
    _numberTextField.textAlignment = NSTextAlignmentCenter;
    _numberTextField.keyboardType = UIKeyboardTypeNumberPad;
    _numberTextField.font = [UIFont systemFontOfSize:_numberFontSize];
    self.currentNumber = [NSString stringWithFormat:@"%zd", _minValue - 1];
    _numberTextField.userInteractionEnabled = _canInputNumber;
    [self addSubview:_numberTextField];
}

#pragma mark - Events
/**
 *  单击按钮逐次加减，长按连续加减
 */
- (void)touchDown:(UIButton *)sender {
    [_numberTextField resignFirstResponder];
    
    if (sender == _increaseBtn) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(increase) userInfo:nil repeats:YES];
    } else {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(decrease) userInfo:nil repeats:YES];
    }
    [_timer fire];
}

- (void)touchUp:(UIButton *)sender {
    [self clearTimer];
}

- (void)increase {
    ![_numberTextField.text isNotBlank] ? _numberTextField.text = self.currentNumber : nil;
    NSInteger number = [_numberTextField.text integerValue] + 1;
    
    if (number <= _maxValue) {
        // 当按钮为"减号按钮隐藏模式",且输入框值==设定最小值,减号按钮展开
        if (_decreaseHide && number == _minValue) {
            [self rotationAnimationMethod];
            [UIView animateWithDuration:0.25 animations:^{
                _decreaseBtn.alpha = 1;
                _decreaseBtn.frame = CGRectMake(0, 0, self.frame.size.height, self.frame.size.height);
            } completion:^(BOOL finished) {
                _numberTextField.hidden = NO;
            }];
        }
        _numberTextField.text = [NSString stringWithFormat:@"%ld", (long)number];
        _numberBlock ? _numberBlock(_numberTextField.text) : nil;
        _delegate ? [_delegate ys_numberView:self number:_numberTextField.text] : nil;
    } else {
        if (_shakeAnimation) { [self shakeAnimationMethod]; }
        [[[UIAlertView alloc] initWithTitle:@"抱歉" message:@"已超过最大值，请重新输入" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil] show];
    }
}

- (void)decrease {
    ![_numberTextField.text isNotBlank] ? _numberTextField.text = [NSString stringWithFormat:@"%ld", (long)_minValue] : nil;
    NSInteger number = [_numberTextField.text integerValue] - 1;
    
    if (number >= _minValue) {
        _numberTextField.text = [NSString stringWithFormat:@"%ld", (long)number];
        _numberBlock ? _numberBlock(_numberTextField.text) : nil;
        _delegate ? [_delegate ys_numberView:self number:_numberTextField.text] : nil;
    } else {
        // 当按钮为"减号按钮隐藏模式",且输入框值 < 设定最小值,减号按钮隐藏
        if (_decreaseHide && number < _minValue) {
            _numberTextField.hidden = YES;
            [self rotationAnimationMethod];
            [UIView animateWithDuration:0.25 animations:^{
                _decreaseBtn.alpha = 0;
                _decreaseBtn.frame = CGRectMake(self.frame.size.width-self.frame.size.height, 0, self.frame.size.height, self.frame.size.height);
            } completion:^(BOOL finished) {
                _numberTextField.text = [NSString stringWithFormat:@"%ld",(long)(_minValue - 1)];
            }];
            return;
        }
        if (_shakeAnimation) { [self shakeAnimationMethod]; }
        [[[UIAlertView alloc] initWithTitle:@"抱歉" message:@"已是最小值，不可再减啦" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil] show];
    }
}

- (void)clearTimer {
    if (_timer.isValid) {
        [_timer invalidate];
        _timer = nil;
    }
}


#pragma mark - UI
- (UIButton *)createButton {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.titleLabel.font = [UIFont boldSystemFontOfSize:_buttonFontSize];
    [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown];
    [button addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpOutside|UIControlEventTouchUpInside|UIControlEventTouchCancel];
    return button;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    CGFloat w = self.frame.size.width;
    CGFloat h = self.frame.size.height;
    _numberTextField.frame = CGRectMake(h, 0, w - 2 * h, h);
    _increaseBtn.frame = CGRectMake(w - h, 0, h, h);
    
    if (_decreaseHide) {
        _numberTextField.hidden = YES;
        _decreaseBtn.alpha = 0;
        _decreaseBtn.frame = _increaseBtn.frame;
        self.backgroundColor = [UIColor clearColor];
    } else {
        _decreaseBtn.frame = CGRectMake(0, 0, h, h);
    }
}

#pragma mark - UITextFieldDelegate
- (void)textFieldDidEndEditing:(UITextField *)textField {
    NSString *minValueString = [NSString stringWithFormat:@"%ld",(long)_minValue];
    NSString *maxValueString = [NSString stringWithFormat:@"%ld",(long)_maxValue];
    
    [textField.text isNotBlank] == NO || textField.text.integerValue < _minValue ? textField.text = minValueString : nil;
    textField.text.integerValue > _maxValue ? textField.text = maxValueString : nil;
    _numberBlock ? _numberBlock(textField.text) : nil;
    _delegate ? [_delegate ys_numberView:self number:textField.text] : nil;
}

#pragma mark - Animations
/**
 * 抖动动画
 */
- (void)shakeAnimationMethod {
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
    CGFloat positionX = self.layer.position.x;
    animation.values = @[@(positionX-10),@(positionX),@(positionX+10)];
    animation.repeatCount = 3;
    animation.duration = 0.07;
    animation.autoreverses = YES;
    [self.layer addAnimation:animation forKey:nil];
}

/**
 * 旋转动画
 */
- (void)rotationAnimationMethod {
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotationAnimation.toValue = @(M_PI*2);
    rotationAnimation.duration = 0.25;
    rotationAnimation.fillMode = kCAFillModeForwards;
    rotationAnimation.removedOnCompletion = NO;
    [_decreaseBtn.layer addAnimation:rotationAnimation forKey:nil];
}

#pragma mark - Settings
- (void)setMinValue:(NSInteger)minValue {
    _minValue = minValue;
    _numberTextField.text = [NSString stringWithFormat:@"%ld",(long)(minValue - 1)];
}

- (void)setBorderColor:(UIColor *)borderColor {
    _borderColor = borderColor;
    
    _decreaseBtn.layer.borderColor = [borderColor CGColor];
    _increaseBtn.layer.borderColor = [borderColor CGColor];
    _numberTextField.layer.borderColor = [borderColor CGColor];
    self.layer.borderColor = [borderColor CGColor];
    
    _decreaseBtn.layer.borderWidth = 0.5;
    _increaseBtn.layer.borderWidth = 0.5;
    _numberTextField.layer.borderWidth = 0.5;
    self.layer.borderWidth = 0.5;
}

- (void)setButtonFontSize:(CGFloat)buttonFontSize {
    _buttonFontSize = buttonFontSize;
    _increaseBtn.titleLabel.font = [UIFont boldSystemFontOfSize:buttonFontSize];
    _decreaseBtn.titleLabel.font = [UIFont boldSystemFontOfSize:buttonFontSize];
}

- (void)setNumberFontSize:(CGFloat)numberFontSize {
    _numberFontSize = numberFontSize;
    _numberTextField.font = [UIFont systemFontOfSize:numberFontSize];
}

- (void)setIncreaseTitle:(NSString *)increaseTitle {
    _increaseTitle = increaseTitle;
    [_increaseBtn setTitle:increaseTitle forState:UIControlStateNormal];
}

- (void)setIncreaseImage:(UIImage *)increaseImage {
    _increaseImage = increaseImage;
    [_increaseBtn setTitle:@"" forState:UIControlStateNormal];
    [_increaseBtn setBackgroundImage:increaseImage forState:UIControlStateNormal];
}

- (void)setDecreaseTitle:(NSString *)decreaseTitle {
    _decreaseTitle = decreaseTitle;
    [_decreaseBtn setTitle:decreaseTitle forState:UIControlStateNormal];
}

- (void)setDecreaseImage:(UIImage *)decreaseImage {
    _decreaseImage = decreaseImage;
    [_decreaseBtn setTitle:@"" forState:UIControlStateNormal];
    [_decreaseBtn setBackgroundImage:decreaseImage forState:UIControlStateNormal];
}

- (NSString *)currentNumber {
    return _numberTextField.text;
}

- (void)setCurrentNumber:(NSString *)currentNumber {
    _numberTextField.text = currentNumber;
}

- (void)setCanInputNumber:(BOOL)canInputNumber {
    if (_canInputNumber == canInputNumber) return;
    _canInputNumber = canInputNumber;
    _numberTextField.userInteractionEnabled = canInputNumber;
}

@end
